package com.github.llyb120.workflow.adapter;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.github.llyb120.workflow.definition.Helper;
import com.github.llyb120.workflow.definition.Workflow;
import com.github.llyb120.workflow.entity.FlowData;
import com.github.llyb120.workflow.entity.WorkflowWrapper;
import lombok.NonNull;
import lombok.SneakyThrows;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class MemoryStorage extends StorageAdapter{

    private Map<String, FlowData> flowDataMap = new ConcurrentHashMap<>();
    private Map<String, WorkflowWrapper> workflowMap = new ConcurrentHashMap<>();

    MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();

    @Override
    public void save(@NonNull final FlowData flowData) {
        if (flowData.getId() == null) {
            throw new RuntimeException();
        }
        flowDataMap.put(flowData.getId(), flowData);
    }


    @Override
    public FlowData findFlowData(@NonNull final String id) {
        FlowData data = flowDataMap.get(id);
        return JSON.parseObject(JSON.toJSONString(data), FlowData.class);
    }

    @Override
    public WorkflowWrapper findWorkFlow(String id) {
        WorkflowWrapper workflow = workflowMap.get(id);
        if (workflow == null) {
            throw new RuntimeException();
        }
        return workflow;
    }


    @SneakyThrows
    @Override
    public void init() {
        ConcurrentHashMap<String, WorkflowWrapper> map = new ConcurrentHashMap<>();
        for (File file : new File("D:\\work\\cal-engine\\demo\\workflow\\flow").listFiles()) {
            String code = FileUtil.readUtf8String(file);
            Helper.ClearElements();
            Helper.Eval(code);
            List elements = Helper.GetElements();
            for (Object element : elements) {
                if(element instanceof Workflow){
                    map.put(((Workflow) element).getId(), new WorkflowWrapper((Workflow) element));
                }
            }
        }
        workflowMap = map;
    }
}
